﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using Kindohm.KSynth.Library;

namespace Kindohm.KSynth.UI
{
    public partial class MainPage : UserControl
    {
        bool loaded;
        Sequencer sequencer;
        VoiceController voiceController;
        SynthMediaStreamSource source;
        Synthesizer synth;

        public MainPage()
        {
            InitializeComponent();
            this.Loaded += new RoutedEventHandler(MainPage_Loaded);
        }

        void MainPage_Loaded(object sender, RoutedEventArgs e)
        {
            this.voiceController = new VoiceController();
            this.loaded = true;

            this.source = new SynthMediaStreamSource(44100, 2);

            Oscillator oscillator = new Oscillator();
            oscillator.Frequency = 0;
            oscillator.WaveForm = new SineWaveForm();
            oscillator.Pan = 0;

            Oscillator oscillator2 = new Oscillator();
            oscillator2.Frequency = 500;
            oscillator2.WaveForm = new SineWaveForm();
            oscillator2.Pan = 0;

            Oscillator oscillator3 = new Oscillator();
            oscillator3.Frequency = 500;
            oscillator3.WaveForm = new SineWaveForm();
            oscillator3.Pan = 0;

            synth = new Synthesizer();

            synth.Oscillators.Add(oscillator);
            synth.Oscillators.Add(oscillator2);
            synth.Oscillators.Add(oscillator3);

            this.presetList.EnvelopeControls = this.envelopeControls;
            this.presetList.Voice1Controls = this.voice1Settings;
            this.presetList.Voice2Controls = this.voice2Settings;
            this.presetList.Voice3Controls = this.voice3Settings;
            this.presetList.PresetSelected += new EventHandler(presetList_PresetSelected);
            this.presetList.DelaySlider = this.delaySlider;
            this.envelopeControls.Synthesizer = synth;

            this.sequencer = new Sequencer();
            this.sequencer.Synthesizer = synth;

            this.sequencerGrid.Sequencer = sequencer;
            this.sequencerGrid.Media = this.media;
            this.source.SampleMaker = sequencer;

            this.voiceController.RegisterOscillator(this.voice1Settings, oscillator);
            this.voiceController.RegisterOscillator(this.voice2Settings, oscillator2);
            this.voiceController.RegisterOscillator(this.voice3Settings, oscillator3);

            WaveFormInfo defaultWaveForm = WaveFormRepository.Instance.FindByName("sin");
            this.voice1Settings.SelectedWaveForm = defaultWaveForm;
            this.voice2Settings.SelectedWaveForm = defaultWaveForm;
            this.voice3Settings.SelectedWaveForm = defaultWaveForm;

            this.voice1Settings.Pan = -100;
            this.voice3Settings.Pan = 100;
            this.tempoSlider_ValueChanged(null, null);
            this.media.SetSource(source);


        }

        void presetList_PresetSelected(object sender, EventArgs e)
        {
            Preset preset = this.presetList.Preset;
            if (preset != null)
            {
                this.envelopeControls.Attack = preset.Attack;
                this.envelopeControls.Sustain = preset.Sustain;
                this.envelopeControls.Decay = preset.Decay;
                this.envelopeControls.Pitch = preset.PitchShift;
                this.delaySlider.Value = preset.DelayLength;

                this.SetVoiceControlsFromPreset(this.voice1Settings, preset.VoicePresets[0]);
                this.SetVoiceControlsFromPreset(this.voice2Settings, preset.VoicePresets[1]);
                this.SetVoiceControlsFromPreset(this.voice3Settings, preset.VoicePresets[2]);

                this.delaySlider_ValueChanged(null, null); //hack
            }
        }

        void SetVoiceControlsFromPreset(VoiceControls settings, VoicePreset preset)
        {
            settings.Pan = preset.Pan;
            settings.Phase = preset.Phase;
            settings.Level = preset.Level;
            settings.Detune = preset.Detune;
            settings.SelectedWaveForm = WaveFormRepository.Instance.FindByName(preset.WaveFormName);
        }

        private void playButton_Checked(object sender, RoutedEventArgs e)
        {
            this.media.Play();
            this.playButtonImage.Visibility = Visibility.Collapsed;
            this.stopButtonImage.Visibility = Visibility.Visible;
            this.sequencerGrid.Start();
        }

        private void playButton_Unchecked(object sender, RoutedEventArgs e)
        {
            this.media.Stop();
            this.playButtonImage.Visibility = Visibility.Visible;
            this.stopButtonImage.Visibility = Visibility.Collapsed;
            this.sequencerGrid.Pause();
        }

        private void tempoSlider_ValueChanged(object sender, EventArgs e)
        {
            if (this.sequencer != null)
                this.sequencer.Tempo = (int)this.tempoSlider.Value;
        }

        private void levelSlider_ValueChanged(object sender, EventArgs e)
        {
            if (loaded)
                this.sequencer.Attenuation = (int)this.levelSlider.Value;
        }

        private void stepSlider_ValueChanged(object sender, EventArgs e)
        {
            if (loaded)
                this.sequencerGrid.StepCount = (int)this.stepSlider.Value;

        }

        private void delaySlider_ValueChanged(object sender, EventArgs e)
        {
            if (loaded)
                this.synth.Delay.Length = (int)delaySlider.Value;
        }
    }
}
